﻿/** \file
* \par Subversion URL:
* \$URL: http://planar-rendering.googlecode.com/svn/trunk/frontend/src/MainForm.cs $
* \version \$Rev: 78 $
* \date    \$Date: 2009-04-20 09:47:39 +0000 (Mon, 20 Apr 2009) $
*/

using System;
using System.Windows.Forms;

namespace Frontend
{
	/// <summary>
	/// The main application form.
	/// </summary>
	public partial class MainForm : Form
	{
		/// <summary>The index to display for the next instantiated function.</summary>
		int nextFuncIndex;

		/// <summary>
		/// The constructor.
		/// </summary>
		public MainForm()
		{
			InitializeComponent();
		}



		/// <summary>
		/// The default empty delegate.
		/// </summary>
		delegate void defaultDelegate();
		/// <summary>
		/// Set the progress bar in a thread-safe manner.
		/// </summary>
		public void IncrementProgress()
		{
			progressGenerate.Invoke((defaultDelegate)delegate()
			{
				if (progressGenerate.Value < progressGenerate.Maximum)
					progressGenerate.Value++;
			});
		}

		/// <summary>
		/// Set the progress bar maximal value in a thread-safe manner.
		/// </summary>
		/// <param name="max">The maximal value to take.</param>
		public void SetProgressMax(int max)
		{
			progressGenerate.Invoke((defaultDelegate)delegate()
			{
				progressGenerate.Value = 0;
				progressGenerate.Maximum = max;
			});
		}

		/// <summary>
		/// Put the form in generation mode.
		/// </summary>
		void BeginGenerate()
		{
			buttonMatlabFile.Enabled = false;
			buttonOrthGenerate.Enabled = false;
			progressGenerate.Show();
		}

		/// <summary>
		/// Take the form out of generation mode.
		/// </summary>
		public void EndGenerate()
		{
			progressGenerate.Invoke((defaultDelegate)delegate()
			{
				buttonMatlabFile.Enabled = true;
				buttonOrthGenerate.Enabled = true;
				progressGenerate.Hide();
				progressGenerate.Value = 0;
			});
		}

		/// <summary>
		/// Add a new function based on the currently selected function factory.
		/// </summary>
		/// <param name="sender">The event sender.</param>
		/// <param name="e">The event arguments.</param>
		void AddFunction(object sender, EventArgs e)
		{
			Function newfunc = Program.AddFunction(nextFuncIndex > 0 ?
				(listFunctionsAvailable.SelectedIndex+1) : 0);

			if (nextFuncIndex != 0)
			{
				string desc = nextFuncIndex.ToString() + ". " + newfunc.GetDescription();
				listFunctionsUsed.Items.Add(desc);
			}

			foreach (Range range in newfunc.ranges)
				tableProps.AddRange(range, nextFuncIndex);
			nextFuncIndex++;
		}

		/// <summary>
		/// Remove the currently selected function.
		/// </summary>
		/// <param name="sender">The event sender.</param>
		/// <param name="e">The event arguments.</param>
		void RemoveFunction(object sender, EventArgs e)
		{
			int index = listFunctionsUsed.SelectedIndex;
			listFunctionsUsed.Items.RemoveAt(index);
			foreach (Range range in Program.generator.funcs[index].ranges)
				tableProps.RemoveRange(range);
			Program.RemoveFunction(index);
		}

		/// <summary>
		/// Called when the form is loaded.
		/// </summary>
		/// <param name="sender">The event sender.</param>
		/// <param name="e">The event arguments.</param>
		void MainForm_Load(object sender, EventArgs e)
		{
			foreach (AbstractFunctionFactory fact in Program.funcsAvailable)
				if (fact.enumIndex > 0)
					listFunctionsAvailable.Items.Add(fact.GetDescription());
			listFunctionsAvailable.SelectedIndex = 0;

			checkMatlabAuto.Checked = true;
			numericImax.Value = Program.generator.con.imax;

			AddFunction(null, null);
		}

		/// <summary>
		/// Selects the file to which the matlab data will be saved.
		/// </summary>
		/// <param name="sender">The event sender.</param>
		/// <param name="e">The event arguments.</param>
		void buttonMatlabFile_Click(object sender, EventArgs e)
		{
			SaveFileDialog dlg = new SaveFileDialog();
			dlg.DefaultExt = "bin";
			dlg.Filter = "Binary files (*.bin)|*.bin|All files (*.*)|*.*";
			if (dlg.ShowDialog() == DialogResult.OK)
				textMatlabFile.Text = dlg.FileName;
		}

		/// <summary>
		/// Starts generation to the matlab target.
		/// </summary>
		/// <param name="sender">The event sender.</param>
		/// <param name="e">The event arguments.</param>
		void buttonMatlabGenerate_Click(object sender, EventArgs e)
		{
			BeginGenerate();

			if (checkMatlabAuto.Checked)
				textMatlabFile.Text = Program.AutoMatlabFilename();
			Program.matlabFilename = textMatlabFile.Text;

			Program.GenerateMatlab();
		}

		/// <summary>
		/// Saves the current function parameters to a file.
		/// </summary>
		/// <param name="sender">The event sender.</param>
		/// <param name="e">The event arguments.</param>
		void buttonSaveSettings_Click(object sender, EventArgs e)
		{
			string filename;
			if (checkSettingsAuto.Checked)
			{
			}
			else
			{
				SaveFileDialog dlg = new SaveFileDialog();
				dlg.DefaultExt = "xml";
				dlg.Filter = "XML files (*.xml)|*.xml|All files (*.*)|*.*";
				if (dlg.ShowDialog() != DialogResult.OK)
					return;
				filename = dlg.FileName;
			}
		}

		/// <summary>
		/// Load some function parameters from a file.
		/// </summary>
		/// <param name="sender">The event sender.</param>
		/// <param name="e">The event arguments.</param>
		void buttonLoadSettings_Click(object sender, EventArgs e)
		{
			OpenFileDialog dlg = new OpenFileDialog();
			dlg.Filter = "XML files (*.xml)|*.xml|All files (*.*)|*.*";
			if (dlg.ShowDialog() != DialogResult.OK)
				return;
		}

		/// <summary>
		/// Switch between setting filename manual and auto mode.
		/// </summary>
		/// <param name="sender">The event sender.</param>
		/// <param name="e">The event arguments.</param>
		void checkSettingsAuto_CheckedChanged(object sender, EventArgs e)
		{
			buttonSaveSettings.Text = checkSettingsAuto.Checked ?
				"&Save" : "&Save...";
		}

		/// <summary>
		/// Switch between matlab filename manual and auto mode.
		/// </summary>
		/// <param name="sender">The event sender.</param>
		/// <param name="e">The event arguments.</param>
		void checkMatlabAuto_CheckedChanged(object sender, EventArgs e)
		{
			buttonMatlabFile.Enabled = !checkMatlabAuto.Checked;
			textMatlabFile.Enabled = !checkMatlabAuto.Checked;
			if (checkMatlabAuto.Checked)
				textMatlabFile.Text = Program.AutoMatlabFilename();
		}

		/// <summary>
		/// Store the imax value.
		/// </summary>
		/// <param name="sender">The event sender.</param>
		/// <param name="e">The event arguments.</param>
		void numericImax_ValueChanged(object sender, EventArgs e)
		{
			Program.generator.con.imax = (int)numericImax.Value;
		}

		/// <summary>
		/// Start the orthagonal rendering generation.
		/// </summary>
		/// <param name="sender">The event sender.</param>
		/// <param name="e">The event arguments.</param>
		void buttonOrthGenerate_Click(object sender, EventArgs e)
		{
			BeginGenerate();
			Program.GenerateOrth();
		}

		/// <summary>
		/// Disable the remove button if there is nothing selected.
		/// </summary>
		/// <param name="sender">The event sender.</param>
		/// <param name="e">The event arguments.</param>
		void listFunctionsUsed_SelectedIndexChanged(object sender, EventArgs e)
		{
			buttonRemoveFunction.Enabled = listFunctionsUsed.SelectedIndex != -1;
		}

		/// <summary>
		/// Called when any of the space radio boxes changes. Stores the value
		/// of the space enum.
		/// </summary>
		/// <param name="sender">The event sender.</param>
		/// <param name="e">The event arguments.</param>
		void radioSpace_CheckedChanged(object sender, EventArgs e)
		{
			Program.generator.space = (Generator.SpaceType)(((RadioButton)sender).Tag);
		}
	}
}
